#include "mybattery.h"
#include "BQ76940.h"
#include "i2c1.h"
#include "retarget.h"

struct BQ76940 MY_BQ76940;
extern int Batteryval[50];
extern unsigned char DSG_STA, CHG_STA;

#define OV_Val 4100 //过充电压
#define UV_Val 2800 //过放电压

int battery_id[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 14};

uint8_t Temp_up_flag, OV_FLAG, UV_FLAG, OC_FLAG;
uint8_t CHG_FLAG, DSG_FLAG;

/**
  * @brief  MyBatteryProtect_Loop 电池保护程序，包括了获取数据以及保护
  * @param  null
  * @retval null
  */
void MyBatteryProtect_Loop() {
    Get_Update_Data();//获取数据

    BQ76940_unpack();//数据解包

    //printf_battery();
//    VOFA_Print();

    OV_Protect();//过充保护
    UV_Protect();//过放保护
    OC_Protect();//过流保护

//    Temp_Protect();//过温保护
}


/**
  * @brief
  * @param
  * @retval
  */
void printf_battery() {
    for (int i = 0; i < 15; i++) {
        if (!IsInBatteryArray(i)) continue;//没有则忽略

        printf("第%i节电池:%imV\r\n", i + 1, MY_BQ76940.battery[i]);
        HAL_Delay(5);
    }
    printf("Sum_Val:%imV\r\n", MY_BQ76940.Sum_val);
    HAL_Delay(5);
    printf("SOC:%i%%\r\n", MY_BQ76940.SOC);
    HAL_Delay(5);
    printf("Current:%imA\r\n", MY_BQ76940.current);
    HAL_Delay(5);
//    printf("Temp:%i℃\r\n", MY_BQ76940.Temp_1);
//    HAL_Delay(5);
}

void VOFA_Print() {
    static int i;
    printf("battery:");
    for (i = 0; i < 19; i++) {
        //if (!IsInBatteryArray(i)) continue;//没有则忽略

        printf("%i,", MY_BQ76940.battery[i]);
    }
    printf("%u,%u", MY_BQ76940.CHG_STA, MY_BQ76940.DSG_STA);
    printf("\r\n");
}

/**
  * @brief  MyBatteryChangeMOS  更改MOS状态
  * @param
  * @retval
  */
void MyBatteryChangeMOS() {
    if (CHG_FLAG) {//充电MOS翻转
        printf("Change CHG_FLAG!");
        if (MY_BQ76940.CHG_STA) Only_Close_CHG();
        else Only_Open_CHG();
        CHG_FLAG = 0;
    }
    if (DSG_FLAG) {//放电MOS翻转
        printf("Change DSG_STA!");
        if (MY_BQ76940.DSG_STA) Only_Close_DSG();
        else Only_Open_DSG();
        DSG_FLAG = 0;
    }
}

/**
  * @brief  BQ76940_unpack 将Batteryval[50]解包到结构体MY_BQ76940里面便于读取
  * @param  null
  * @retval null
  */
void BQ76940_unpack() {
    static int i;

    //子电池数据转存
    for (i = 0; i < 15; i++) {
        MY_BQ76940.battery[i] = Batteryval[i];
    }

    //总电池电压
    MY_BQ76940.Sum_val = Batteryval[15];
    //SOC
    MY_BQ76940.SOC = Batteryval[16];
    //电流
    MY_BQ76940.current = Batteryval[17];
    //温度
    MY_BQ76940.Temp_1 = Batteryval[18];
    //充电MOS
    MY_BQ76940.CHG_STA = CHG_STA;
    //放电MOS
    MY_BQ76940.DSG_STA = DSG_STA;
}


/**
  * @brief  OV_Protect 过充保护
  * @param  null
  * @retval null
  */
void OV_Protect() {
    static int i;

    if (OV_FLAG == 1) {
        for (i = 0; i < 15; i++) {
            if (!IsInBatteryArray(i)) continue;//没有则忽略

            if (MY_BQ76940.battery[i] > OV_Val - 50) {
                return;//有一个不满足继续充电的情况则直接return
            }
            //否则打开充电MOS
            Only_Open_CHG();
            IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
            OV_FLAG = 0;
        }
    } else {
        for (i = 0; i < 15; i++) {
            if (!IsInBatteryArray(i)) continue;//没有则忽略

            if (MY_BQ76940.battery[i] > OV_Val) {
                printf("OV! %i:%i > %i", i, MY_BQ76940.battery[i], OV_Val);
                Only_Close_CHG();
                IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
                OV_FLAG = 1;
                return;
            }
        }
    }
}

/**
  * @brief  UV_Protect 过放保护
  * @param  null
  * @retval null
  */
void UV_Protect() {
    static int i;
    if (UV_FLAG == 1) {
        for (i = 0; i < 15; i++) {
            if (!IsInBatteryArray(i)) continue;//没有则忽略

            if (MY_BQ76940.battery[i] < UV_Val + 10) {
                return;//有一个不满足继续充电的情况则直接return
            }
            //否则允许打开放电mos
            Only_Open_DSG();
            IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
            UV_FLAG = 0;
        }
    } else {
        for (i = 0; i < 15; i++) {
            if (!IsInBatteryArray(i)) continue;//没有则忽略

            if (MY_BQ76940.battery[i] < UV_Val) {
                printf("UV!");
                Only_Close_DSG();
                IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
                UV_FLAG = 1;
                return;
            }
        }
    }
}

/**
  * @brief  OC_Protect 过流保护
  * @param  null
  * @retval null
  */
void OC_Protect() {
    if (MY_BQ76940.current > 3500)//如果电流大于2000ma，关闭充放电MOS管
    {

        Close_DSG_CHG();
        IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
        OC_FLAG = 1;
    }
    if (OC_FLAG == 1) {
        if (MY_BQ76940.current < 3500)//如果电流大于2000ma，关闭充放电MOS管
        {
            Open_DSG_CHG();
            IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
            OC_FLAG = 0;
        }
    }
}

/**
  * @brief  Temp_Protect 过温保护
  * @param  null
  * @retval null
  */
void Temp_Protect() {
    if (MY_BQ76940.Temp_1 > 50)//如果电流大于2000ma，关闭充放电MOS管
    {
        Close_DSG_CHG();
        IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
        Temp_up_flag = 1;
    }
    if (Temp_up_flag == 1) {
        if (MY_BQ76940.Temp_1 < 40) {
            Open_DSG_CHG();
            IIC1_write_one_byte_CRC(SYS_STAT, 0xFF); //清除状态
            Temp_up_flag = 0;
        }

    }
}

/**
  * @brief  IsInBatteryArray判断是否为使用的电池
  * @param  battery_id 电池id，现实中需要+1
  * @retval 存在为1，否则为0
  */
uint8_t IsInBatteryArray(int id) {
    static int battery_num = sizeof(battery_id);//获取电池个数
    static int i;
    for (i = 0; i < battery_num; i++) {
        if (id == battery_id[i]) return 1;
    }
    return 0;
}